//
//----------------------------------------------
// Original project: 
// by  Stewart Lynch on 2024-12-16
//
// Follow me on Mastodon: @StewartLynch@iosdev.space
// Follow me on Threads: @StewartLynch (https://www.threads.net)
// Follow me on X: https://x.com/StewartLynch
// Follow me on LinkedIn: https://linkedin.com/in/StewartLynch
// Subscribe on YouTube: https://youTube.com/@StewartLynch
// Buy me a ko-fi:  https://ko-fi.com/StewartLynch
//----------------------------------------------
// Copyright © 2024 CreaTECH Solutions. All rights reserved.

import Foundation

public class APIService {
    public let urlString: String
    public init(urlString: String) {
        self.urlString = urlString
    }
    
    public func getJSON<T: Decodable>() async throws(APIError) -> T {
        guard let url = URL(string: urlString) else {
            throw .invalidURL
        }
        do {
            let (data, response) = try await URLSession.shared.data(from: url)
            guard let httpResponse = response as? HTTPURLResponse,
                  httpResponse.statusCode == 200
            else {
                throw APIError.invalidResponseStatus
            }
            let decoder = JSONDecoder()
            do {
                let decodedData = try decoder.decode(T.self, from: data)
                return decodedData
            } catch {
                throw APIError.decodingError(error.localizedDescription)
            }
        } catch {
            throw .dataTaskError(error.localizedDescription)
        }
    }
}

public enum APIError: Error, LocalizedError {
    case invalidURL
    case dataTaskError(String)
    case invalidResponseStatus
    case decodingError(String)
    
    public var errorDescription: String? {
        switch self {
            case .invalidURL:
                NSLocalizedString("The endpoint URL is invalid.", comment: "")
            case .dataTaskError(let string):
                string
            case .invalidResponseStatus:
                NSLocalizedString("The API failed to issue a valid response", comment: "")
            case .decodingError(let string):
                string
        }
    }
}
